package com.demo2do.fms.entity.supplier.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;

import com.demo2do.core.format.PersistentFormat;
import com.demo2do.fms.entity.authority.Branch;

/**
 * 服务供方主表
 * 
 * @author Ysy
 */
@Entity
@Table(name = "FMS_SUPPLIER")
@DynamicInsert
@DynamicUpdate
@PersistentFormat
public class Supplier {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
    @SequenceGenerator(name = "generator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
    private Long id;

    /** 
     * 公司代码
     * 
     * 来自 MDM (引入时写入)
     */
    private String code;
    
    /** 公司现用名称   */
    private String name;
    
    /** 公司简称  */
    private String shortName;
    
    /** 是否是VAM供方 */
    @Column(name = "is_vam")
    private boolean vam;
    
    /** 
     * 组织ID
     *
     * 来自 MDM (引入时写入)
     */
    private Long orgId;
    
    /** 默认分区 */
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @PersistentFormat(key=String.class)
    private Branch branch;
        
    /** 公司类型 */
    @Column(name = "SUPPLIER_TYPE")
    @Enumerated(EnumType.ORDINAL)
    private Type type;
    
    /** 公司级别  */
    @Column(name = "SUPPLIER_LEVEL")
    @Enumerated(EnumType.ORDINAL)
    private Level level;
    
    /** 审核状态 */
    @Enumerated(EnumType.ORDINAL)
    private AuditStatus status;
    
    /** 申报状态 */
    @Enumerated(EnumType.ORDINAL)
    private SyncStatus syncStatus;
    
    /** 
     * 业务类型
     *    运输供方: 离地运输-01、地跑运输-02、水铁运输-03
     *    仓储供方: 仓储管理-04、车辆检查-05、短驳驾驶-06、PDI-07、动态维护-08、洗车-09、维修-11
     */
    private String businessType;
    
    /** 业务性质 */
    @Enumerated(EnumType.STRING)
    private BusinessNature businessNature;
    
    /** 创建者 */
    private Long creator;
    
    /** 创建时间  */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    
    /** 最后修改者 */
    private Long lastOperator;
    
    /** 最后修改时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date lastModifyTime;
    
    @Column(name = "is_disabled")
    private boolean disabled;
    
    /**
     * the default constructor
     */
    public Supplier() {
    }

    /**
     * 
     * @param id
     * @param name
     */
    public Supplier(Long id, String name) {
        this.id = id;
        this.name = name;
    }
    
    /**
     * @param operator
     * @return
     */
    public Supplier initliaze(Long operator) {
        this.status= AuditStatus.EDITING;
        this.disabled = false;
        this.creator = operator;
        this.createTime = new Date();
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * 更新简称
     * 
     * @param shortName
     * @param operator
     * @return
     */
    public Supplier editShortname(String shortName, Long operator) {
        this.shortName = shortName;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @param operator
     * @return
     */
    public Supplier operate(Long operator) {
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @param lastModifyTime
     * @param lastOperator
     * @return
     */
    public Supplier operate(Date lastModifyTime, Long lastOperator) {
    	this.lastModifyTime = lastModifyTime;
    	this.lastOperator = lastOperator;
    	return this;
    }
    
    /**
     * 
     * @param status
     * @param operator
     * @return
     */
    public Supplier editStatus(AuditStatus status, Long operator) {
        this.status = status;
        this.lastModifyTime = new Date();
        this.lastOperator = operator;
        return this;
    }
    
    /**
     * 
     * @param syncStatus
     * @param operator
     * @return
     */
    public Supplier editSyncStatus(SyncStatus syncStatus, Long operator) {
        this.syncStatus = syncStatus;
        this.lastModifyTime = new Date();
        this.lastOperator = operator;
        return this;
    }
    
    /**
     * @param status
     * @param now
     * @param operator
     * @return
     */
    public Supplier rectify(AuditStatus status, Date now, Long operator) {
        this.status = status;
        this.lastOperator = operator;
        this.lastModifyTime = now;
        return this;
    }
    
    /**
     * @param level
     * @return
     */
    public Supplier changeLevel(Level level) {
    	this.level = level;
    	return this;
    }
    
    /**
     * @param branch
     * @param operator
     * @return
     */
    public Supplier changeBranch(Branch branch, Long operator) {
    	this.branch = branch;
    	this.lastOperator = operator;
    	this.lastModifyTime = new Date();
    	return this;
    }
    
    /**
     * @param operator
     * @return
     */
    public Supplier disable(Long operator) {
        this.disabled = true;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * 
     * @param version
     * @param operator
     * @return
     */
    public Supplier change(SupplierModifiedVersion version, Long operator) {
        this.name = version.getName();
        this.syncStatus = SyncStatus.ADOPT;
        this.lastModifyTime = new Date();
        this.lastOperator = operator;
        return this;
    }
    
    /**
     * @return
     */
    public String inValidMessage() {
        
        if (StringUtils.isBlank(code)) {
            return "公司代码不存在";
        } else if (StringUtils.isBlank(name)) {
            return "公司名称不存在";
        } else if (StringUtils.isBlank(shortName)) {
            return "公司简称不存在";
        } else {
            return null;
        }
        
    }
    
    /**
     * @return
     */
    @Transient
    public String getIdString() {
        return String.valueOf(this.id);
    }
    
    /**
     * @return
     */
    @Transient
    public boolean isMotor() {
        return Type.MOTOR.equals(type);
    }
    
    /**
     * @return
     */
    @Transient
    public boolean isStorage() {
        return Type.STORAGE.equals(type);
    }
    
    /**
     * @return
     */
    @Transient
    public boolean isFirst() {
    	return Level.FIRST.equals(level);
    }
    
    /**
     * @return
     */
    @Transient
    public boolean isSecond() {
        return Level.SECOND.equals(level);
    }

    /**
     * 业务类型展示
     * 
     * @return
     */
    @Transient
    public String getBusinessTypeDescription() {
        
        if (StringUtils.isBlank(businessType)) {
            return null;
        }
        
        List<String> codes = Arrays.asList(StringUtils.split(businessType, ","));
        List<String> displays = new ArrayList<String>();
        for (String code : codes) {
            BusinessType type = BusinessType.codeOf(code);
            displays.add(type.getDescription());
        }
        
        return StringUtils.join(displays, "、");
        
    }
    
    /**
     * 业务类型设置
     * 
     * @param businessTypes
     */
    public void setBusinessTypes(List<String> businessTypes) {
        this.businessType = StringUtils.join(businessTypes, ",");
    }
    
    /**
     * 审核通过校验
     * 
     * @return
     */
    public String couldAdopt() {
        if (StringUtils.isBlank(businessType)) {
            return "业务类型未录入";
        } else if (businessNature == null) {
            return "业务性质未录入";
        } else {
            return null;
        }
    }
    
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the shortName
     */
    public String getShortName() {
        return shortName;
    }
    
    /**
     * @return
     */
    public boolean isVam() {
        return vam;
    }

    /**
     * @return the orgId
     */
    public Long getOrgId() {
        return orgId;
    }

    /**
     * @return the branch
     */
    public Branch getBranch() {
        return branch;
    }

    /**
     * @return the type
     */
    public Type getType() {
        return type;
    }

    /**
     * @return the level
     */
    public Level getLevel() {
        return level;
    }

    /**
     * @return the status
     */
    public AuditStatus getStatus() {
        return status;
    }

    /**
     * @return the syncStatus
     */
    public SyncStatus getSyncStatus() {
        return syncStatus;
    }
    
    /**
     * @return
     */
    public String getBusinessType() {
        return businessType;
    }
    
    /**
     * @return
     */
    public BusinessNature getBusinessNature() {
        return businessNature;
    }

    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * @return the lastModifyTime
     */
    public Date getLastModifyTime() {
        return lastModifyTime;
    }

    /**
     * @return the creator
     */
    public Long getCreator() {
        return creator;
    }

    /**
     * @return the lastOperator
     */
    public Long getLastOperator() {
        return lastOperator;
    }

    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param code the code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param shortName the shortName to set
     */
    public void setShortName(String shortName) {
        this.shortName = shortName;
    }
    
    /**
     * @param vam
     */
    public void setVam(boolean vam) {
        this.vam = vam;
    }

    /**
     * @param orgId the orgId to set
     */
    public void setOrgId(Long orgId) {
        this.orgId = orgId;
    }

    /**
     * @param branch the branch to set
     */
    public void setBranch(Branch branch) {
        this.branch = branch;
    }

    /**
     * @param type the type to set
     */
    public void setType(Type type) {
        this.type = type;
    }

    /**
     * @param level the level to set
     */
    public void setLevel(Level level) {
        this.level = level;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(AuditStatus status) {
        this.status = status;
    }

    /**
     * @param syncStatus the syncStatus to set
     */
    public void setSyncStatus(SyncStatus syncStatus) {
        this.syncStatus = syncStatus;
    }
    
    /**
     * @param businessType
     */
    public void setBusinessType(String businessType) {
        this.businessType = businessType;
    }
    
    /**
     * @param businessNature
     */
    public void setBusinessNature(BusinessNature businessNature) {
        this.businessNature = businessNature;
    }

    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * @param lastModifyTime the lastModifyTime to set
     */
    public void setLastModifyTime(Date lastModifyTime) {
        this.lastModifyTime = lastModifyTime;
    }

    /**
     * @param creator the creator to set
     */
    public void setCreator(Long creator) {
        this.creator = creator;
    }

    /**
     * @param lastOperator the lastOperator to set
     */
    public void setLastOperator(Long lastOperator) {
        this.lastOperator = lastOperator;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }
    
    
}
